package de.teamgamma.cansat.groundstation.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

import de.teamgamma.cansat.groundstation.transmitting.TransmitOptions;

/**
 * Java Socket server to send data to the smartphone
 * @author Alexander Ciupka
 */
		
public class Server implements Runnable {

	private ServerSocket server;
	private ArrayList<PrintWriter> list_clientWriter;
	private Messages e;
	private TransmitOptions transmitOptions;
	private Hostednetwork network;
	
	public Server() {
		e = new Messages();	
		network = new Hostednetwork();
	}
	
	/**
	 * ClientHandler class which handles the Clients on the Server
	 * @author Alexander Ciupka
	 */
	
	public class ClientHandler implements Runnable {
		Socket client;
		BufferedReader reader;

		/**
		 * constructor where a new BufferedReader is created for the new client
		 * @param client The new client
		 */
		
		public ClientHandler(Socket client) {
			try {
				this.client = client;
				reader = new BufferedReader(new InputStreamReader(
						client.getInputStream()));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 * run Method which checks if there is a new received JSON and send it to the client
		 */
		
		@Override
		public void run() {
			while (true) {
				String message;
				e.input();

				while (e.next()) {
					message = e.sendMessages();
					sendToAllClients(message);
				}
				try {
					Thread.sleep(50);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * Endless loop which checks for new Clients
	 */
	
	public void listenToClients() {
		while (true) {
			try {
				Socket client = server.accept();
				System.out.println("Client connected");
				PrintWriter writer = new PrintWriter(client.getOutputStream());
				list_clientWriter.add(writer);
				Thread clientThread = new Thread(new ClientHandler(client));
				clientThread.start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * starts the Java Socket Server with the port 5555 
	 * @return if the server creation was successful
	 */
	
	public boolean runServer() {
		try {
			server = new ServerSocket(5555);
			list_clientWriter = new ArrayList<PrintWriter>();
			return true;
		} catch (IOException e) {

			e.printStackTrace();
			return false;
		}
	}

	/**
	 * iterates over all clients and send them a message
	 * @param message which will be send to the clients
	 */
	
	public void sendToAllClients(String message) {
		@SuppressWarnings("rawtypes")
		Iterator it = list_clientWriter.iterator();
		while (it.hasNext()) {
			PrintWriter writer = (PrintWriter) it.next();
			writer.println(message);
			writer.flush();
		}
	}

	/**
	 * Run method which will start the server if it's desired
	 */
	
	@Override
	public void run() {
		network.startNetwork();
		transmitOptions = TransmitOptions.getInstance();
		while(true) {
			if(transmitOptions.checkSendToSmartphone()) {
				if (runServer()) {
					listenToClients();
				}
			}
		}
	}
}